/*
 * Copyright 2021 TiKV Project Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.webank.tikv.util;

public interface BackOffer {

    int REDIS_EXEC_MAX_BACKOFF = 5 * 1000;
    int PD_INFO_BACKOFF = 5 * 1000;

    /**
     * doBackOff sleeps a while base on the BackOffType. Will stop until
     * max back off time exceeded.
     */
    boolean doBackOff(BoType type, Exception err);

    default long nextBackOffTime(BoType type, Exception err) {
        return -1;
    }

    /**
     * BackoffWithMaxSleep sleeps a while base on the backoffType and
     * never sleep more than maxSleepMs for each sleep.
     */
    boolean doBackOffWithMaxSleep(BoType type, long maxSleepMs, Exception err);

    /**
     * check if deadline exceeded.
     */
    void checkTimeout();

    /**
     * canRetryAfterSleep sleeps a while base on the BackOffType. Will
     * stop until max back off time exceeded and throw an exception to the caller. It will return
     * false if the total sleep time has exceeded some limit condition.
     */
    boolean canRetryAfterSleep(BoType type);

    // Back off strategies
    enum Strategy {
        // NoJitter makes the backoff sequence strict exponential.
        NoJitter,
        // FullJitter applies random factors to strict exponential.
        FullJitter,
        // EqualJitter is also randomized, but prevents very short sleeps.
        EqualJitter,
        // DecorrJitter increases the maximum jitter based on the last random value.
        DecorrJitter
    }

    enum BoType {
        BoTiKVRPC,
        BoPDRPC,

        BoRegionMiss,
        BoRegionScheduling,
        BoRegionRecoveryInProgress,
        BoMaxRegionNotInitialized,

        BoUpdateLeader,
        BoServerBusy,
        BoDiskFull,
        BoTsoBatchUsedUp,
        BoMaxTsNotSynced,

        BoIsWitness,
        BoStaleCmd,
        BoCheckTimeout,
        BoCheckHealth,

        BoTxnNotFound,
        BoTxnLock,
        BoTxnLockFast,
    }

}
